﻿/// 通用函数封装
#ifndef CVCALIBCOMMON_H
#define CVCALIBCOMMON_H

#include <opencv2/core.hpp>

class CvCalibCommon
{

public:
    ///
    /// \brief 查找所有的角点坐标
    /// \param image
    /// \param boardSize
    /// \param corners 输出的值
    /// \return true 找到，false没有
    ///
    static bool findChessboardCorners(cv::Mat &image, cv::Size &boardSize, std::vector<cv::Point2f> &corners);

    //! [compute_errors]
    static double computeReprojectionErrors(
            const std::vector<std::vector<cv::Point3f> >& objectPoints,
            const std::vector<std::vector<cv::Point2f> >& imagePoints,
            const std::vector<cv::Mat>& rvecs, const std::vector<cv::Mat>& tvecs,
            const cv::Mat& cameraMatrix, const cv::Mat& distCoeffs,
            std::vector<float>& perViewErrors );

    /// 理想uv转成畸变uv
    static cv::Point2f uvToDistortedUV(cv::Point2f &uv, cv::Mat &intrinsic, cv::Mat &intrinsicInvert, cv::Mat &distCoeffs);

    ///
    /// \brief 将世界坐标系中的点投影到左右相机成像坐标系中
    ///
    static cv::Point2f xyz2uv(cv::Point3f worldPoint,float intrinsic[3][3],float translation[1][3],float rotation[3][3],
        double distCoeffs[5]);

    ///
    /// \brief 将世界坐标系中的点投影到左右相机成像坐标系中
    /// \param worldPoint
    /// \param intrinsic 内参
    /// \param R 默认单位矩阵
    /// \param T 默认为0
    /// \param distCoeffs
    /// \param isDistorted 结果是否是畸变
    /// \return
    ///
    static cv::Point2f xyz2uv(cv::Point3f &worldPoint,cv::Mat &intrinsic, cv::Mat &R, cv::Mat &T,
        cv::Mat &distCoeffs, bool isDistorted=true); // isDistorted 默认是有校验的

    ///
    /// \brief 根据左右相机中成像坐标求解空间坐标
    /// \param uvLeft 矫正后的像素位置
    /// \param uvRight 矫正后的像素位置
    /// \param leftIntrinsic
    /// \param leftRotation
    /// \param leftTranslation
    /// \param rightIntrinsic
    /// \param rightRotation
    /// \param rightTranslation
    /// \return
    ///
    static cv::Point3f uv2xyz(cv::Point2f &uvLeft, cv::Point2f &uvRight,
                cv::Mat &leftIntrinsic, cv::Mat &leftRotation, cv::Mat &leftTranslation,
                cv::Mat &rightIntrinsic, cv::Mat &rightRotation, cv::Mat &rightTranslation);


    ///
    /// \brief findLightBalls
    /// \param grayImage 输入图像
    /// \param nThresh
    /// \param outPoints
    /// \param rMin 半径最小值
    ///
    static void findLightBalls(cv::Mat &grayImage, int nThresh, std::vector<cv::Point2f> &outPoints,
                               const float rMin = 3.0);

};

#endif // CVCALIBCOMMON_H
